package com.yanqu.road.server.gameplayer.module.travel;

import com.yanqu.road.entity.config.beauty.BeautyUnlockArg;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.log.LogTravel;
import com.yanqu.road.entity.messageSubscribe.entity.MessageUserNoticeData;
import com.yanqu.road.entity.player.UserBeauty;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.entity.player.UserPatronsSkill;
import com.yanqu.road.entity.player.UserTravel;
import com.yanqu.road.entity.task.args.union.UnionActivityTaskArgs;
import com.yanqu.road.entity.travel.*;
import com.yanqu.road.logic.bussiness.player.UserTravelBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.TravelPb;
import com.yanqu.road.pb.travel.TravelProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.*;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.server.manger.activity.curio.CurioMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.config.SkillMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.config.TravelMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.messagesubscribe.MessageSubscribeMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.LocalDateTimeHelper;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.*;

/**
 * 玩家游历模块
 */
public class TravelModule extends GeneralModule {

	private UserTravel userTravel;

	private int lastSaveTimePower = -1;					//上线前最后一次保存的用户游历体力数据 用于找回

	public TravelModule(GamePlayer player) {
		super(player);
	}

	@Override
	public boolean loadData() {
		userTravel = UserTravelBussiness.getUserTravel(player.getUserId());
		if (userTravel != null){
			lastSaveTimePower = userTravel.getPower();
		}
		calcPower();
		return true;
	}

	@Override
	public boolean afterLoadData() {
		if(SystemOpenMgr.systemOpen(player, eSystemId.Travel.getValue())){
			initTravel();
		}
		return true;
	}

	@Override
	public void afterLogin() {
		syncUserTravel();
		syncBeautyTrystTravelBuff();
	}

	@Override
	public void loginSendMsg() {

	}

	@Override
	public boolean saveData() {
		if (null != userTravel) {
			if (userTravel.isInsertOption()) {
				UserTravelBussiness.addUserTravel(userTravel);
			} else if (userTravel.isUpdateOption()) {
				UserTravelBussiness.updateUserTravel(userTravel);
			}
		}
		return true;
	}

	public void initTravelSystem() {
		initTravel();
		//同步游历信息
		syncUserTravel();
	}

	public void syncUserTravel(){
		if (null != userTravel) {
			TravelProto.TravelTempMsg.Builder msg = TravelPb.parseTravelTempMsg(userTravel);
			if(null != msg) {
				player.sendPacket(Protocol.U_TRAVEL_INFO, msg);
			}
		}
	}

	public void syncTravelPower(){
		TravelProto.TravelPowerMsg.Builder msg = TravelPb.parseTravelPowerMsg(userTravel);
		if(null != msg){
			player.sendPacket(Protocol.U_TRAVEL_POWER_SYNC, msg);
		}
	}

	private void initTravel() {
		if (null == userTravel) {
			UserTravel travel = new UserTravel();
			travel.setUserId(player.getUserId());
			travel.setCityId(0);
			travel.setTravelTimes(0);
			travel.setPower(TravelMgr.getMaxTravelPower(player.getTitleId()));
			travel.setLastRestoreTime(System.currentTimeMillis() / 1000);
			travel.setModifyTime(System.currentTimeMillis() / 1000);
			travel.setInsertOption();
			userTravel = travel;
		}
	}

	public UserTravel getUserTravel() {
		return userTravel;
	}

	public void resetOneDay(){
		long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp() / 1000;
		if(null != userTravel){
			if(userTravel.getModifyTime() < zeroTime){
				userTravel.setTravelTimes(0);
				userTravel.clearTodayEventTimes();
				userTravel.setModifyTime(zeroTime);
				syncUserTravel();
			}
		}
	}

	/**
	 * 计算体力值恢复
	 */
	public void calcPower() {
		if(null == userTravel){
			return;
		}
		long nowTime = System.currentTimeMillis() / 1000;
		long lastRestoreTime = userTravel.getLastRestoreTime();
		int maxPower = TravelMgr.getMaxTravelPower(player.getTitleId());
		int powerRestoreTime = GameConfig.TRAVEL_POWER_RESTORE_TIME;
		if(userTravel.getPower() < maxPower){
			//恢复次数
			int restoreTimes = (int) ((nowTime - lastRestoreTime) / powerRestoreTime);
			if (restoreTimes < 0) {
				restoreTimes = 0;
			}
			int power = userTravel.getPower();
			// 当前值 + 恢复指 如果超过最大值
			if (restoreTimes + power >= maxPower) {
				power = maxPower;
				userTravel.setLastRestoreTime(nowTime);
			} else {
				power = power + restoreTimes;
				userTravel.setLastRestoreTime(lastRestoreTime + powerRestoreTime * restoreTimes);
			}
			userTravel.setPower(power);
		}else {
			userTravel.setLastRestoreTime(nowTime);
		}
	}

	//什么时候会恢复满，微信推送
	private void travelRecoveryTime(){
		if(!MessageSubscribeMgr.isSwitch()){
			return;
		}
		long nowTime = System.currentTimeMillis();
		long recoveryTime = 0;

		int maxEnergy = TravelMgr.getMaxTravelPower(player.getTitleId());
		long energyRestoreTime = GameConfig.TRAVEL_POWER_RESTORE_TIME * 1000;
		if(userTravel.getPower() < maxEnergy){
			recoveryTime = nowTime + energyRestoreTime * (maxEnergy - userTravel.getPower());
		}
		MessageUserNoticeData noticeData = MessageSubscribeMgr.getUserNoticeData(player.getUserId());
		noticeData.setTravelTime(recoveryTime);
	}


	/**
	 * 扣除体力值
	 */
	private boolean reducePower() {
		calcPower();
		if (userTravel.getPower() > 0) {
			userTravel.setPower(userTravel.getPower() - 1);
			syncTravelPower();
			return true;
		}
		return false;
	}

	/**
	 * 游历
	 */
	public TravelResult travel(int travelType) {
		TravelResult travelResult = new TravelResult();
		if(null == userTravel){
			travelResult.setRet(GameErrorCode.E_TRAVEL_IS_LOCK);
			return travelResult;
		}
		calcPower();
		if(userTravel.getEventCount() > 0){
			travelResult.setRet(GameErrorCode.E_TRAVEL_HAS_EVENT_NO_FINISH);
			return travelResult;
		}
		if(userTravel.getPower() < 1){
			travelResult.setRet(GameErrorCode.E_TRAVEL_POWER_NO_ENOUGH);
			//触发现金礼包，体力丹道具不足
			// 2023/12/08 优化：删除体力丹道具判断
//			if(!player.getModule(BagModule.class).hasEnoughGoods(GameConfig.GAME_ITEM_TRAVEL_ADD_POWER_TIMES, 1)) {
				player.notifyListener(eGamePlayerEventType.RechargeTravel.getValue(), 0);
//			}
			player.notifyListener(eGamePlayerEventType.RechargeTravelNew.getValue(), 0);
			return travelResult;
		}
		if(1 == travelType){
			TravelGain travelGain = travelOne();
			if(travelGain.getRet() != 0){
				travelResult.setRet(travelGain.getRet());
				return travelResult;
			}
			travelResult.setRet(0);
			travelResult.addTravelGain(travelGain);
			if(userTravel.getPower() < 1){
				player.notifyListener(eGamePlayerEventType.RechargeTravelNew.getValue(), 0);
			}
			return travelResult;
		}else if(2 == travelType){
			if(!TravelMgr.canTravelAll(player)){
				travelResult.setRet(GameErrorCode.E_TRAVEL_CAN_NO_MULTI);
				return travelResult;
			}
			int times = Math.min(userTravel.getPower(),ConfigMgr.getTravelMultiTimes());
			travelResult = batchTravel(times,true);
			if(userTravel.getPower() < 1){
				player.notifyListener(eGamePlayerEventType.RechargeTravelNew.getValue(), 0);
			}
			return travelResult;
		}else {
			travelResult.setRet(GameErrorCode.E_TRAVEL_TYPE_ERROR);
			return travelResult;
		}
	}

	private TravelGain travelOne(){
		TravelGain travelGain = new TravelGain();
		if(!reducePower()){//扣除体力
			travelGain.setRet(GameErrorCode.E_TRAVEL_POWER_NO_ENOUGH);
			return travelGain;
		}
		TravelDefaultEvent travelDefaultEvent = ConfigMgr.getTravelDefaultEvent(userTravel.getTotalTravelTimes());
		TravelCity travelCity;
		TravelEvent travelEvent;
		if(null != travelDefaultEvent){
			travelCity = TravelMgr.getTravelCity(travelDefaultEvent.getCityId());
			travelEvent = TravelMgr.getTravelEvent(travelDefaultEvent.getEventId());
		}else {
			travelCity = TravelMgr.getRandomTravelCity(userTravel.getCityId());
			travelEvent = TravelMgr.getCityTravelEvent(player, travelCity);
		}
		userTravel.setCityId(travelCity.getCityId());
		//游历次数加1
		userTravel.setTravelTimes(userTravel.getTravelTimes() + 1);
		userTravel.setTotalTravelTimes(userTravel.getTotalTravelTimes() + 1);
		//成就、任务
		player.notifyListener(eGamePlayerEventType.TravelTimes.getValue(), 1);
		player.notifyListener(eGamePlayerEventType.UnionTravelTimes.getValue(), new UnionActivityTaskArgs(UnionActivityTaskArgs.TYPE_ADD_VALUE, 1, player.getUserInfo().getUnionUid()));
		player.notifyListener(eGamePlayerEventType.TravelTotalTimes.getValue(), userTravel);
		if(null != travelEvent){
			if(eTravelEventType.BeautyEvent.getValue() == travelEvent.getEventType() || eTravelEventType.HasBeautyEvent.getValue() == travelEvent.getEventType()){
				int beautyId = 0;
				int addValue;
				for(Map.Entry<Integer, BigInteger> dataEntry : travelEvent.getReward().getGoods().entrySet()){
					beautyId = dataEntry.getKey();
					break;
				}
				if(GoodsMgr.isBeautyGoods(beautyId)){
					UserBeauty userBeauty = player.getModule(BeautyModule.class).getUserBeauty(beautyId);
					userTravel.setTotalBeautyEncounterTimes(userTravel.getTotalBeautyEncounterTimes() + 1);
					if(null != userBeauty){
						addValue = 1;
						player.getModule(BeautyModule.class).addIntimacy(userBeauty, addValue, eLogMoneyType.Beauty.getValue(), eLogMoneyType.BeautyEncounter.getValue());
						//同步美女信息
						player.getModule(BeautyModule.class).syncUserBeauty(userBeauty);
					}
					//成就、任务
					player.notifyListener(eGamePlayerEventType.BeautyTotalEncounterTimes.getValue(), userTravel);
				}
			}else if(eTravelEventType.MultiChildEvent.getValue() == travelEvent.getEventType()){//生双胞胎
				userTravel.addMultiChildType(1);
				syncBeautyTrystTravelBuff();
			}else if(eTravelEventType.DealEvent.getValue() == travelEvent.getEventType()){//交易事件
				doDealEvent(travelGain, travelEvent);
			}else if(eTravelEventType.AppointTrystEvent.getValue() == travelEvent.getEventType() || eTravelEventType.BrothelEvent.getValue() == travelEvent.getEventType() ||
					eTravelEventType.PatronsWineEvent.getValue() == travelEvent.getEventType() || eTravelEventType.CasinoEvent.getValue() == travelEvent.getEventType() ||
					eTravelEventType.DrinkEvent.getValue() == travelEvent.getEventType()){
				userTravel.addEventId(travelEvent.getId());
			}else {
				travelGain.getReward().addProperty(travelEvent.getReward());
			}
			userTravel.addTravelEventTimes(travelEvent.getId());
			userTravel.addTodayEventTimes(travelEvent.getId());
			player.notifyListener(eGamePlayerEventType.TravelTotalEventTimes.getValue(), userTravel);
			Property prestigeReward = TravelMgr.getPrestigeReward(player);
			//周卡特权
			DailyDataModule dailyDataModule = player.getModule(DailyDataModule.class);
			if(player.getModule(CardModule.class).travelPrestigeDouble(dailyDataModule.getWeekCardTravelTimes())){
				prestigeReward.rideProperty(2);
				dailyDataModule.addWeekCardTravelTimes(1);
				dailyDataModule.syncWeekCardDailyData();
			}
			travelGain.getReward().addProperty(prestigeReward);
			travelGain.setEventId(travelEvent.getId());
			player.getModule(CurrencyModule.class).addCurrency(travelGain.getReward(), eLogMoneyType.Travel, eLogMoneyType.TravelGet);
			//日志
			Property logReward = new Property(travelEvent.getReward());
			logReward.addProperty(prestigeReward);

			AutoLogMgr.add(new LogTravel(player.getUserId(), userTravel.getTravelTimes(), userTravel.getCityId(), travelEvent.getId(),
					PropertyHelper.parsePropertyToString(logReward)));
		}else {
			log.error("travel event is empty,userId:{},travelTimes:{},cityId:{}", player.getUserId(), userTravel.getTravelTimes(), travelCity.getCityId());
		}
		try {
			travelRecoveryTime();
		}catch (Exception e){
			log.error("error:" + e);
		}
		return travelGain;
	}

	/**
	 * 批量游历
	 * @param times
	 * @return
	 */
	public TravelResult batchTravel(int times,boolean notifyTask){		//第二个参数控制加不加每日任务
		TravelResult travelResult = new TravelResult();
		calcPower();
		if (userTravel.getPower() < times) {
			travelResult.setRet(GameErrorCode.E_TRAVEL_POWER_NO_ENOUGH);
			return travelResult;
		}
		userTravel.setPower(userTravel.getPower() - times);
		syncTravelPower();
		Set<UserBeauty> needSynUserBeautySet = new HashSet<>();
		boolean needSynBeautyTrystTravelBuff = false;
		Property reward = new Property();
		boolean syncWeekDailyMsg = false;
		DailyDataModule dailyDataModule = player.getModule(DailyDataModule.class);
		for (int i = 0; i < times; i++) {
			TravelGain travelGain = new TravelGain();
			// 随机事件
			TravelDefaultEvent travelDefaultEvent = ConfigMgr.getTravelDefaultEvent(userTravel.getTotalTravelTimes() + i);
			TravelCity travelCity;
			TravelEvent travelEvent;
			if(null != travelDefaultEvent){
				travelCity = TravelMgr.getTravelCity(travelDefaultEvent.getCityId());
				travelEvent = TravelMgr.getTravelEvent(travelDefaultEvent.getEventId());
			}else {
				travelCity = TravelMgr.getRandomTravelCity(userTravel.getCityId());
				travelEvent = TravelMgr.getCityTravelEvent(player, travelCity);
			}
			userTravel.setCityId(travelCity.getCityId());
			if(null != travelEvent) {
				if (eTravelEventType.BeautyEvent.getValue() == travelEvent.getEventType() || eTravelEventType.HasBeautyEvent.getValue() == travelEvent.getEventType()) {
					int beautyId = 0;
					int addValue;
					for (Map.Entry<Integer, BigInteger> dataEntry : travelEvent.getReward().getGoods().entrySet()) {
						beautyId = dataEntry.getKey();
						break;
					}
					if (GoodsMgr.isBeautyGoods(beautyId)) {
						UserBeauty userBeauty = player.getModule(BeautyModule.class).getUserBeauty(beautyId);
						userTravel.setTotalBeautyEncounterTimes(userTravel.getTotalBeautyEncounterTimes() + 1);
						if (null != userBeauty) {
							addValue = 1;
							player.getModule(BeautyModule.class).addIntimacy(userBeauty, addValue, eLogMoneyType.Beauty.getValue(), eLogMoneyType.BeautyEncounter.getValue());
							needSynUserBeautySet.add(userBeauty);
						}
					}
				} else if (eTravelEventType.MultiChildEvent.getValue() == travelEvent.getEventType()) {//生双胞胎
					userTravel.addMultiChildType(1);
					needSynBeautyTrystTravelBuff = true;
				} else if(eTravelEventType.DealEvent.getValue() == travelEvent.getEventType()){//交易事件
					doDealEvent(travelGain, travelEvent);
				}else if (eTravelEventType.AppointTrystEvent.getValue() == travelEvent.getEventType() || eTravelEventType.BrothelEvent.getValue() == travelEvent.getEventType() ||
						eTravelEventType.PatronsWineEvent.getValue() == travelEvent.getEventType() || eTravelEventType.CasinoEvent.getValue() == travelEvent.getEventType() ||
						eTravelEventType.DrinkEvent.getValue() == travelEvent.getEventType()) {
					userTravel.addEventId(travelEvent.getId());
				} else {
					travelGain.getReward().addProperty(travelEvent.getReward());
				}
				userTravel.addTravelEventTimes(travelEvent.getId());
				userTravel.addTodayEventTimes(travelEvent.getId());

				Property prestigeReward = TravelMgr.getPrestigeReward(player);
				//周卡特权
				if(player.getModule(CardModule.class).travelPrestigeDouble(dailyDataModule.getWeekCardTravelTimes())){
					prestigeReward.rideProperty(2);
					dailyDataModule.addWeekCardTravelTimes(1);
					syncWeekDailyMsg = true;
				}
				travelGain.getReward().addProperty(prestigeReward);
				travelGain.setEventId(travelEvent.getId());
				reward.addProperty(travelGain.getReward());

				//日志
				Property logReward = new Property(travelEvent.getReward());
				logReward.addProperty(prestigeReward);

				AutoLogMgr.add(new LogTravel(player.getUserId(), userTravel.getTravelTimes(), userTravel.getCityId(), travelEvent.getId(),
						PropertyHelper.parsePropertyToString(logReward)));
				travelResult.getTravelGainList().add(travelGain);
			}else{
				log.error("travel event is empty,userId:{},travelTimes:{},cityId:{}", player.getUserId(), userTravel.getTravelTimes(), travelCity.getCityId());
			}
		}

		//游历次数
		userTravel.setTravelTimes(userTravel.getTravelTimes() + times);
		userTravel.setTotalTravelTimes(userTravel.getTotalTravelTimes() + times);
		//成就、任务
		if (notifyTask){
			player.notifyListener(eGamePlayerEventType.TravelTimes.getValue(), times);
			player.notifyListener(eGamePlayerEventType.UnionTravelTimes.getValue(), new UnionActivityTaskArgs(UnionActivityTaskArgs.TYPE_ADD_VALUE, times, player.getUserInfo().getUnionUid()));
		}

		player.notifyListener(eGamePlayerEventType.TravelTotalTimes.getValue(), userTravel);
		//成就、任务
		player.notifyListener(eGamePlayerEventType.BeautyTotalEncounterTimes.getValue(), userTravel);

		player.notifyListener(eGamePlayerEventType.TravelTotalEventTimes.getValue(), userTravel);

		// 同步的美女集合
		//同步美女信息
		for(UserBeauty item : needSynUserBeautySet){
			player.getModule(BeautyModule.class).syncUserBeauty(item);
		}
		// 同步双胞胎buff
		if(needSynBeautyTrystTravelBuff){
			syncBeautyTrystTravelBuff();
		}
		if(syncWeekDailyMsg){
			dailyDataModule.syncWeekCardDailyData();
		}
		// 加道具
		player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.Travel, eLogMoneyType.TravelGet);
		try {
			travelRecoveryTime();
		}catch (Exception e){
			log.error("error:" + e);
		}
		return travelResult;
	}

	private void doDealEvent(TravelGain travelGain, TravelEvent travelEvent) {
		List<Integer> weightList = StringUtils.stringToIntegerList(travelEvent.getParamStr(), "\\|");
		List<String> rewardList = StringUtils.stringToStringList(travelEvent.getRewardStr(), "\\|");
		UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(102420);
		if(userPatrons != null){
			for (UserPatronsSkill patronsSkill : userPatrons.getSkillList()) {
				SkillInfo skillInfo = SkillMgr.getSkillInfo(patronsSkill.getSkillId());
				if(skillInfo != null && eSkillType.TrainCasinoDiceWin.getValue() == skillInfo.getType()){
					String reward = rewardList.get(rewardList.size() - 1);
					travelGain.getReward().addProperty(PropertyHelper.parseStringToProperty(reward));
					return;
				}
			}
		}else {
			int index = RandomHelper.getRandomIndexByWeight(weightList, new Random());
			String reward = rewardList.get(index);
			if (!StringUtils.isNullOrEmpty(reward) && !"0".equals(reward)) {
				travelGain.getReward().addProperty(PropertyHelper.parseStringToProperty(reward));
			}
		}
	}

	public TravelResult travelAll(int times){
		TravelResult travelResult = new TravelResult();
		for(int i = 0; i < times; i++){
			TravelGain travelGain = travelOne();
			if (0 == travelGain.getRet()) {
				travelResult.addTravelGain(travelGain);
			}
		}
		travelResult.setRet(0);
		return travelResult;
	}

	//指定传唤美女
	public TravelSelectObjectResult selectTrystBeauty(TravelEvent travelEvent, int beautyId,int type){
		TravelSelectObjectResult selectObjectResult = new TravelSelectObjectResult();
		UserBeauty userBeauty = player.getModule(BeautyModule.class).getUserBeauty(beautyId);
		if(null == userBeauty){
			log.info("selectTrystBeauty get beauty no find,userId:{},eventId:{},objectId:{}",player.getUserId(), travelEvent.getId(), beautyId);
			userBeauty = player.getModule(BeautyModule.class).getFirstIndexBeauty();       //加个容错，如果传参数据异常，给挑个美女
		}
		if(null == userBeauty){
			selectObjectResult.setRet(GameErrorCode.E_BEAUTY_NO_FOUND);
			log.info("selectTrystBeauty get beauty no find and no any beauty,userId:{},eventId:{},objectId:{}",player.getUserId(), travelEvent.getId(), beautyId);
			userTravel.removeEventId();
			return selectObjectResult;
		}
		userTravel.removeEventId();
		userTravel.addBeautyTryst(userBeauty.getBeautyId());

		syncBeautyTrystTravelBuff();

		selectObjectResult.setEventId(travelEvent.getId());
		selectObjectResult.setObjectId(userBeauty.getBeautyId());

		log.info("指定传唤美女 type:{},userId:{},传入的beautyId：{},实际的美女Id：{},totalIntimacy:{},beautyTrystList:{}",type,player.getUserId(),beautyId,userBeauty.getBeautyId(),userBeauty.getTotalIntimacy(),userTravel.getBeautyTrystList());
		return selectObjectResult;
	}

	//选择青楼互动美女
	public TravelSelectObjectResult selectBrothelBeauty(TravelEvent travelEvent, int beautyId){
		TravelSelectObjectResult selectObjectResult = new TravelSelectObjectResult();
		if(!ConfigMgr.isBrothelBeauty(beautyId)){
			log.info("selectBrothelBeauty beauty no brothel beauty,userId:{},eventId:{},objectId:{}",player.getUserId(), travelEvent.getId(), beautyId);
			beautyId = ConfigMgr.getFirstBrothelBeauty();
			if(0 == beautyId){
				log.info("selectBrothelBeauty beauty no brothel beauty,config no brothel beauty,userId:{},eventId:{},objectId:{}",player.getUserId(), travelEvent.getId(), beautyId);
				userTravel.removeEventId();
				selectObjectResult.setRet(GameErrorCode.E_BEAUTY_NO_FOUND);
				return selectObjectResult;
			}
		}
		userTravel.setBrothelBeautyId(beautyId);
		selectObjectResult.setEventId(travelEvent.getId());
		selectObjectResult.setObjectId(beautyId);
		return selectObjectResult;
	}

	//指定共饮门客
	public TravelSelectObjectResult selectWinePatrons(TravelEvent travelEvent, int patronsId,int type){
		TravelSelectObjectResult selectObjectResult = new TravelSelectObjectResult();
		UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(patronsId);
		if(null == userPatrons){
			log.info("selectWinePatrons get patrons no find,userId:{},eventId:{},objectId:{}",player.getUserId(), travelEvent.getId(), patronsId);
			userPatrons = player.getModule(PatronsModule.class).getFirstIndexPatrons();       //加个容错，如果传参数据异常，给随个门客
		}
		if(null == userPatrons){
			selectObjectResult.setRet(GameErrorCode.E_PATRONS_NO_FOUND);
			log.info("selectTrystBeauty get patrons no find and no any patrons,userId:{},eventId:{},objectId:{}",player.getUserId(), travelEvent.getId(), patronsId);
			userTravel.removeEventId();
			return selectObjectResult;
		}
		userTravel.removeEventId();
		//增加门客能力
		long addAbility = 0;
		for(Map.Entry<Integer, BigInteger> dataEntry : travelEvent.getReward().getGoods().entrySet()){
			addAbility = dataEntry.getValue().longValue();
			break;
		}
		userPatrons.setAddAbility(userPatrons.getAddAbility().add(BigInteger.valueOf(addAbility)));
		player.getModule(PatronsModule.class).onPatronsChange(userPatrons);
		player.getModule(PatronsModule.class).syncPatronsData(userPatrons);
		selectObjectResult.setEventId(travelEvent.getId());
		selectObjectResult.setObjectId(userPatrons.getPatronsId());
		selectObjectResult.setAddValue(addAbility);

		log.info("指定共饮门客 type:{},userId:{},传入的patronsId：{},实际的patronsId：{},ability:{},addAbility:{}", type, player.getUserId(), patronsId, userPatrons.getPatronsId(), userPatrons.getAbility(),addAbility);
		return selectObjectResult;
	}

	//选择赌坊对赌类型
	public TravelSelectObjectResult selectCasinoType(TravelEvent travelEvent, int casinoType){
		TravelSelectObjectResult selectObjectResult = new TravelSelectObjectResult();
		if(!ConfigMgr.isCasinoType(casinoType)){
			log.info("selectCasinoType casinoType invalid,userId:{},eventId:{},objectId:{}",player.getUserId(), travelEvent.getId(), casinoType);
			casinoType = 1;
		}
		userTravel.setCasinoType(casinoType);
		selectObjectResult.setEventId(travelEvent.getId());
		selectObjectResult.setObjectId(casinoType);
		return selectObjectResult;
	}

	//选择赌坊对赌类型
	public TravelSelectObjectResult selectIsDrink(TravelEvent travelEvent, int isDrink){
		TravelSelectObjectResult selectObjectResult = new TravelSelectObjectResult();
		if(isDrink > 0){
			Property consume = new Property(GameConfig.GAME_MONEY_INGOTS, BigInteger.valueOf(GameConfig.DRINK_INTERACTIVE_COST));
			if(!player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.Travel, eLogMoneyType.TravelDrinkCost)){
				selectObjectResult.setRet(GameErrorCode.E_BAG_INGOTS_NO_ENOUGH);
				return selectObjectResult;
			}
			selectObjectResult.getConsume().addProperty(consume);
			DrinkInteractiveType interactiveType = ConfigMgr.getRandomDrinkInteractiveType();
			addPower(interactiveType.getAddTravelPowerCount());
			selectObjectResult.setAddValue(interactiveType.getAddTravelPowerCount());
			selectObjectResult.setObjectId(interactiveType.getType());
		}
		//移除事件
		userTravel.removeEventId();
		selectObjectResult.setEventId(travelEvent.getId());
		return selectObjectResult;
	}

	//选择青楼交互方式
	public TravelSelectObjectResult selectBrothelInteractiveType(TravelEvent travelEvent, int type){
		TravelSelectObjectResult selectObjectResult = new TravelSelectObjectResult();
		int beautyId = userTravel.getBrothelBeautyId();
		if(!ConfigMgr.isBrothelBeauty(beautyId)){
			log.info("selectInteractiveType but no brothel beauty,userId:{},eventId:{},beautyId:{},type:{}",player.getUserId(), travelEvent.getId(), beautyId, type);
			beautyId = ConfigMgr.getFirstBrothelBeauty();
			if(0 == beautyId){
				log.info("selectInteractiveType but no brothel beauty,userId:{},eventId:{},type:{}",player.getUserId(), travelEvent.getId(), type);
				userTravel.removeEventId();
				selectObjectResult.setRet(GameErrorCode.E_BEAUTY_NO_FOUND);
				return selectObjectResult;
			}
		}
		BrothelInteractiveType brothelInteractiveType = ConfigMgr.getBrothelInteractiveType(type);
		if(null == brothelInteractiveType){
			log.info("selectInteractiveType no find interactive type,userId:{},eventId:{},type:{}",player.getUserId(), travelEvent.getId(), type);
			brothelInteractiveType = ConfigMgr.getBrothelInteractiveType(1);
			if(null == brothelInteractiveType){
				log.info("selectInteractiveType config no interactive type,userId:{},eventId:{},beautyId:{},type:{}",player.getUserId(), travelEvent.getId(), beautyId, type);
				userTravel.removeEventId();
				selectObjectResult.setRet(GameErrorCode.E_TRAVEL_INTERACTIVE_TYPE_NO_FOUND);
				return selectObjectResult;
			}
		}
		if(!brothelInteractiveType.getConsume().isNothing()){
			if(!player.getModule(CurrencyModule.class).removeCurrency(brothelInteractiveType.getConsume(), eLogMoneyType.Travel, eLogMoneyType.TravelBrothelCost)){
				selectObjectResult.setRet(GameErrorCode.E_BAG_INGOTS_NO_ENOUGH);
				return selectObjectResult;
			}
			selectObjectResult.getConsume().addProperty(brothelInteractiveType.getConsume());
		}
		UserBeauty userBeauty = player.getModule(BeautyModule.class).getUserBeauty(beautyId);
		if(null != userBeauty){
			player.getModule(BeautyModule.class).addIntimacy(userBeauty, brothelInteractiveType.getUnlockValue(), eLogMoneyType.Beauty.getValue(), eLogMoneyType.BeautyEncounter.getValue());
			//同步美女信息
			player.getModule(BeautyModule.class).syncUserBeauty(userBeauty);
		}else {
			player.notifyListener(eGamePlayerEventType.BeautyUnlock.getValue(), new BeautyUnlockArg(beautyId, brothelInteractiveType.getUnlockValue()));
		}
		//恢复互动对象
		userTravel.setBrothelBeautyId(0);
		//移除事件
		userTravel.removeEventId();
		selectObjectResult.setEventId(travelEvent.getId());
		selectObjectResult.setObjectId(beautyId);
		selectObjectResult.setAddValue(brothelInteractiveType.getUnlockValue());
		return selectObjectResult;
	}

	//选择赌坊对赌大小
	public TravelSelectObjectResult selectCasinoValue(TravelEvent travelEvent, int casinoValue){
		TravelSelectObjectResult selectObjectResult = new TravelSelectObjectResult();
		int casinoType = userTravel.getCasinoType();
		if(!ConfigMgr.isCasinoType(casinoType)){
			log.error("selectCasinoValue but no casinoType,userId:{},eventId:{},casinoType:{},casinoValue:{}",player.getUserId(), travelEvent.getId(),
					casinoType, casinoValue);
			casinoType = 1;
		}
		CasinoInteractiveType interactiveType = ConfigMgr.getCasinoInteractiveType(casinoType);
		if(null == interactiveType){
			log.error("selectCasinoValue no find interactive type,userId:{},eventId:{},casinoType:{},casinoValue:{}",player.getUserId(),
					travelEvent.getId(), casinoType, casinoValue);
			userTravel.removeEventId();
			selectObjectResult.setRet(GameErrorCode.E_TRAVEL_CASINO_TYPE_NO_FOUND);
			return selectObjectResult;
		}
		if(casinoValue > interactiveType.getDiceCount()){
			log.error("selectCasinoValue casinoValue over diceCount,userId:{},eventId:{},casinoType:{},casinoValue:{},diceCount:{}",player.getUserId(), travelEvent.getId(),
					casinoType, casinoValue, interactiveType.getDiceCount());
			casinoValue = interactiveType.getDiceCount();
		}
		//门客天赋，稳赢
		int skillValue = player.getModule(PatronsModule.class).getTalentSkillAddition(eSkillType.TrainCasinoDiceWin.getValue(), 0);
		List<Integer> diceList;
		boolean isWin;
		if(interactiveType.getDiceCount() <= skillValue || userTravel.getTotalCasinoTimes() < GameConfig.TRAVEL_CASINO_MUST_WIN_PARAM){
			diceList = TravelMgr.getWinDiceValueList(interactiveType.getDiceCount(), casinoValue);
			isWin = true;
		}else {
			diceList = TravelMgr.getDiceValueList(interactiveType.getDiceCount());
			isWin = TravelMgr.isCasinoWin(diceList, casinoValue);
		}
		if(isWin){
			player.getModule(CurrencyModule.class).addCurrency(interactiveType.getReward(), eLogMoneyType.Travel, eLogMoneyType.TravelCasinoGet);
			selectObjectResult.setAddValue(interactiveType.getRewardIngotsCount());
		}
		userTravel.setTotalCasinoTimes(userTravel.getTotalCasinoTimes() + 1);
		//恢复赌坊对赌类型
		userTravel.setCasinoType(0);
		//移除事件
		userTravel.removeEventId();
		selectObjectResult.setEventId(travelEvent.getId());
		selectObjectResult.setObjectId(casinoValue);
		selectObjectResult.setParam(StringUtils.listToString(diceList, ","));
		return selectObjectResult;
	}

	/**
	 * 道具恢复体力
	 */
	public void recoverPower(GoodsInfo goodsInfo, long count){
		long addCount = goodsInfo.getParamList().get(0).longValue() * count;
		addPower((int) addCount);
	}

	/**
	 * 增加体力
	 */
	public void addPower(int addCount){
		calcPower();
		userTravel.setPower(userTravel.getPower() + addCount);
		syncTravelPower();
		try {
			travelRecoveryTime();
		}catch (Exception e){
			log.error("error:" + e);
		}
	}

	/**
	 * 是否有双胞胎事件
	 */
	public boolean isMakeMultiChild(){
		if(null == userTravel){
			return false;
		}
		int remainingSite = player.getModule(ChildModule.class).getRemainingChildSiteCount();
		if(remainingSite <= 0) {//没有空着子嗣席位，不能增加子嗣
			return false;
		}
		return userTravel.getMultiChildTypeList().size() > 0;
	}

	/**
	 * 移除双胞胎事件
	 */
	public int removeMakeMultiChildEvent(){
		if(null == userTravel){
			return 0;
		}
		int type = userTravel.removeMultiChildType();
		if(type!=0){
			syncBeautyTrystTravelBuff();
		}
		return type;
	}

	public int removeBeautyTrystEvent(){
		if(null == userTravel){
			return 0;
		}
		int beautyId = userTravel.removeBeautyTryst();
		if (beautyId != 0) {
			syncBeautyTrystTravelBuff();
		}
		return beautyId;
	}

	/**
	 * 累计游历次数
	 */
	public long getTotalTravelTimes(){
		if(null != userTravel){
			return userTravel.getTotalTravelTimes();
		}
		return 0;
	}

	public void syncBeautyTrystTravelBuff() {
		TravelProto.syncBeautyTrystTravelBuffRespMsg.Builder builder = TravelProto.syncBeautyTrystTravelBuffRespMsg.newBuilder();
		if (userTravel != null) {
			builder.setChooseBeautyTimes(userTravel.getBeautyTrystList().size());
			builder.setMultiChildTimes(userTravel.getMultiChildTypeList().size());
		} else {
			builder.setChooseBeautyTimes(0);
			builder.setMultiChildTimes(0);
		}
		player.sendPacket(ClientProtocol.U_BEAUTY_TRYST_TRAVEL_BUFF_SYNC, builder);
	}

	public int getLastSaveTimePower() {
		return lastSaveTimePower;
	}

	/**
	 * 看广告游历
	 * @param times
	 * @return
	 */
	public TravelProto.TravelGoRespMsg.Builder watchAdTravel(int times) {
		//游历前的赚速
		String preEarnSpeed = player.getUserInfo().getEarnSpeed().toString();
		TravelModule travelModule = player.getModule(TravelModule.class);
		//添加体力
		travelModule.addPower(times);
		//游历掉
		TravelResult travelResult = travelModule.batchTravel(times, false);
		//构造PB
		UserTravel userTravel = player.getModule(TravelModule.class).getUserTravel();
        return TravelPb.createTravelGoRespMsg(travelResult, userTravel, preEarnSpeed, player.getUserInfo().getEarnSpeed().toString());
	}
}
